#!/bin/bash
# 脚本所在目录
basedir=$(cd $(dirname $0);pwd)
HOST_IP="192.168.100.1"
# 备份路径
DATA_BACKUP_DIR="/publish/backups/mysqlbk"
# xtrabackup安装目录
XTRABACKUP_INSTALL_DIR="/usr/local/xtrabackup"
# MYSQL连接信息
MYSQL_HOST='127.0.0.1'
MYSQL_PORT='3306'
MYSQL_USER='root' 
MYSQL_PASSWORD='subushi123'
# 使用的MySQL配置文件
MYSQL_CNF_FILE='/publish/scripts/mysqlbackups/mysql.cnf'
# 数据备份策略(空格分割，0为星期日)
FULL_BACKUP_TIME=(0)
INCREMENT_BACKUP_TIME=(1 2 3 4 5 6)
# 是否使用代理发送消息(默认关闭)
PROXY_NETWORK_STATUS="false"
PROXY_NETWORK_URL='192.168.100.1:22334'
# 企业微信群机器人地址
WECHAT_ROBOT_URL=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=*****
# 备份保留数量(默认为1)
FULL_BACKUP_FILE_SAVE_NUM=1
INCREMENT_BACKUP_FILE_SAVE_NUM=1
######################
# 日志打印模块
logs () {
    if [[ ! -e ${basedir}/logs ]];then
      mkdir -p ${basedir}/logs
    fi
    echo "$*" >> ${basedir}/logs/backup_scripts_$(date +%Y%m%d).log
}
# 发送消息到企业微信群机器人模块
send_wechat_work_robot () {
    local CURL_CMD="curl"
    if [[ ${1} = '0' ]];then
        local BACKUP_STATUS="成功"
        local SUGGEST="无"
        local color="info"
    elif [[ ${1} = '1' ]];then
        local BACKUP_STATUS="失败"
        local SUGGEST="$3"
        local color="red"
    fi
    if [[ ${2} = 'full' ]];then
        local BACKUP_TYPE="全量"
    elif [[ ${2} = 'incr' ]];then
        local BACKUP_TYPE="增量"
    fi
    if [[ ${PROXY_NETWORK_STATUS} = 'true' ]];then
        CURL_CMD="${CURL_CMD} --proxy ${PROXY_NETWORK_URL}"
    fi
    ${CURL_CMD} "${WECHAT_ROBOT_URL}" \
    -H 'Content-Type: application/json' \
    -d "
    {
        \"msgtype\": \"markdown\",
        \"markdown\": {
            \"content\": \"======== **通知** ========\n
             >**通知主题**: MySQL 数据备份
             >**备份类型**: ${BACKUP_TYPE}
             >**执行主机**: ${HOST_IP}
             >**备份开始时间**: ${SCRIPTS_START_TIME}
             >**备份结束时间**: $(date +%Y/%m/%d--%T)
             >**备份情况**: <font color=\\\"${color}\\\">**${BACKUP_STATUS}**</font>
             >**处理措施**: <font color=\\\"comment\\\">${SUGGEST}</font>\"
        }
    }
    "
}
# 全量备份模块
full_data_backup_start () {
    logs "$(date +%Y/%m/%d--%T)       全量数据备份开始"
    INCREMENT_BASE_DIR=$(find ${DATA_BACKUP_DIR}/backups -maxdepth 1 -type d | grep -E "full|increment")
    DATA_BACKUP_START_TIME=$(date +%Y%m%d_%H%M%S)
    mkdir -p ${DATA_BACKUP_DIR}/{backups,logs}
    ${XTRABACKUP_INSTALL_DIR}/bin/xtrabackup --defaults-file="${MYSQL_CNF_FILE}" --host="${MYSQL_HOST}" --port="${MYSQL_PORT}" --user="${MYSQL_USER}" --password="${MYSQL_PASSWORD}" --parallel=2  --compress --compress-threads=2 --backup --target-dir="${DATA_BACKUP_DIR}/backups/full_${DATA_BACKUP_START_TIME}" >> ${DATA_BACKUP_DIR}/logs/full_${DATA_BACKUP_START_TIME}.log 2>&1
    if [[ $? = 0 ]];then
        logs "$(date +%Y/%m/%d--%T)       全量数据备份成功"
        if [[ ${INCREMENT_BASE_DIR} ]];then
            logs "$(date +%Y/%m/%d--%T)       开始压缩上一备份数据"
            tar -cJf ${INCREMENT_BASE_DIR}.tar.xz ${INCREMENT_BASE_DIR}
            if [[ $? = 0 ]];then
                logs "$(date +%Y/%m/%d--%T)       压缩上一备份数据成功"
                rm -fr ${INCREMENT_BASE_DIR}
                logs "$(date +%Y/%m/%d--%T)       全量数据备份完成"
                send_wechat_work_robot 0 full
            else
                logs "$(date +%Y/%m/%d--%T)       压缩上一备份数据失败，请手动处理"
                send_wechat_work_robot 1 full "压缩上一备份数据失败，请手动处理"
                exit 1
            fi
        else
            send_wechat_work_robot 0 full
        fi
    else
        logs "$(date +%Y/%m/%d--%T)       全量数据备份失败，请手动处理"
        send_wechat_work_robot 1 full "全量数据备份失败，请手动处理"
        exit 1
    fi
}
# 增量备份模块
increment_data_backup_start () {
    cd ${DATA_BACKUP_DIR}
    FULL_BACKUP_FILE_NUM=$(find ${DATA_BACKUP_DIR}/backups -maxdepth 1 -name "full_*" | wc -l)
    ONLY_ONE_DIR_STATUS=$(find ${DATA_BACKUP_DIR}/backups -maxdepth 1 -type d | grep -E "full|increment" | wc -l)
    if [[ ${FULL_BACKUP_FILE_NUM} = 0 ]];then
        logs "$(date +%Y/%m/%d--%T)       未找到全量备份文件，开始全量数据备份"
        full_data_backup_start
    elif [[ ${ONLY_ONE_DIR_STATUS} != '1' ]];then
        logs "$(date +%Y/%m/%d--%T)       备份路径目录不唯一，无法进行数据备份，请手动处理"
        send_wechat_work_robot 1 incr "备份路径目录不唯一，无法进行数据备份，请手动处理"
        exit 1
    else
        INCREMENT_BASE_DIR=$(find ${DATA_BACKUP_DIR}/backups -maxdepth 1 -type d | grep -E "full|increment")
        if [[ ${INCREMENT_BASE_DIR} ]];then
            logs "$(date +%Y/%m/%d--%T)       增量数据备份开始"
            DATA_BACKUP_START_TIME=$(date +%Y%m%d_%H%M%S)
            ${XTRABACKUP_INSTALL_DIR}/bin/xtrabackup --defaults-file="${MYSQL_CNF_FILE}" --host="${MYSQL_HOST}" --port="${MYSQL_PORT}" --user="${MYSQL_USER}" --password="${MYSQL_PASSWORD}" --parallel=2  --compress --compress-threads=2    --backup   --incremental-basedir="${INCREMENT_BASE_DIR}" --target-dir="${DATA_BACKUP_DIR}/backups/increment_${DATA_BACKUP_START_TIME}" >> ${DATA_BACKUP_DIR}/logs/increment_${DATA_BACKUP_START_TIME}.log 2>&1
            if [[ $? = 0 ]];then
                logs "$(date +%Y/%m/%d--%T)       增量数据备份成功"
                logs "$(date +%Y/%m/%d--%T)       开始压缩上一备份数据"
                tar -cJf ${INCREMENT_BASE_DIR}.tar.xz ${INCREMENT_BASE_DIR}
                if [[ $? = 0 ]];then
                    logs "$(date +%Y/%m/%d--%T)       压缩上一备份数据成功"
                    rm -fr ${INCREMENT_BASE_DIR}
                    logs "$(date +%Y/%m/%d--%T)       增量数据备份完成"
                    send_wechat_work_robot 0 incr
                else
                    logs "$(date +%Y/%m/%d--%T)       压缩上一备份数据失败，请手动处理"
                    send_wechat_work_robot 1 incr "压缩上一备份数据失败，请手动处理"
                    exit 1
                fi
            else
              logs "$(date +%Y/%m/%d--%T)       增量数据备份失败，请手动处理"
              send_wechat_work_robot 1 incr "增量数据备份失败，请手动处理"
              exit 1
            fi
        else
            logs "$(date +%Y/%m/%d--%T)       未找到上次备份数据目录，开始全量数据备份"
            full_data_backup_start
        fi
    fi
}
# 过期文件删除模块
delete_dateline_backup_file () {
    FULL_BACKUP_FILE_SUM=$(ls -t1 ${DATA_BACKUP_DIR}/backups/full_*.tar.xz | wc -l)
    INCREMENT_BACKUP_FILE_SUM=$(ls -t1 ${DATA_BACKUP_DIR}/backups/increment*.tar.xz | wc -l)
    if [[ ${FULL_BACKUP_FILE_SUM} -gt ${FULL_BACKUP_FILE_SAVE_NUM:-1} ]];then
        DELETE_COUNT_FULL=$(( ${FULL_BACKUP_FILE_SUM} - ${FULL_BACKUP_FILE_SAVE_NUM:-1} ))
        logs "$(date +%Y/%m/%d--%T)       开始删除过期文件：$(ls -t1 ${DATA_BACKUP_DIR}/backups/full_*.tar.xz | tail -n ${DELETE_COUNT_FULL})"
        ls -t1 ${DATA_BACKUP_DIR}/backups/full_*.tar.xz | tail -n ${DELETE_COUNT_FULL} | xargs rm -fr
    elif [[ ${INCREMENT_BACKUP_FILE_SUM} -gt ${INCREMENT_BACKUP_FILE_SAVE_NUM:-1} ]];then
        DELETE_COUNT_INCREMENT=$(( ${INCREMENT_BACKUP_FILE_SUM} - ${INCREMENT_BACKUP_FILE_SAVE_NUM:-1} ))
        logs "$(date +%Y/%m/%d--%T)       开始删除过期文件：$(ls -t1 ${DATA_BACKUP_DIR}/backups/increment*.tar.xz | tail -n ${DELETE_COUNT_INCREMENT})"
        ls -t1 ${DATA_BACKUP_DIR}/backups/increment*.tar.xz | tail -n ${DELETE_COUNT_INCREMENT} | xargs rm -fr
    fi
}
# 备份策略检测模块
bakcup_tactics_check () {
    FULL_BACKUP_TIME_UNIQ=(`echo ${FULL_BACKUP_TIME[@]}|sed -e 's/ /\n/g'|sort -nu|sed -e ':a;N;s/\n/ /g;ta'`)
    INCREMENT_BACKUP_TIME_UNIQ=(`echo ${INCREMENT_BACKUP_TIME[@]}|sed -e 's/ /\n/g'|sort -nu|sed -e ':a;N;s/\n/ /g;ta'`)
    for f_time in ${FULL_BACKUP_TIME[@]}
    do
        if [[ ${f_time} = $(date +%w) ]];then
            FULL_BACKUP_STATUS_UP='true'
        fi
        if [[ ${f_time} -lt 0 || ${f_time} -gt 6 ]];then
            send_wechat_work_robot 1 11 "全量备份时间配置不符合一周时间，请手动处理"
            exit 1
        fi
        for i_time in ${INCREMENT_BACKUP_TIME[@]}
        do
            if [[ ${i_time} -lt 0 || ${i_time} -gt 6 ]];then
                send_wechat_work_robot 1 11 "增量备份时间配置不符合一周时间，请手动处理"
                exit 1
            fi
            if [[ ${i_time} = $(date +%w) ]];then
                INCREMENT_BACKUP_STATUS_UP='true'
            fi
            if [[ ${f_time} = ${i_time} ]];then
                FULL_AND_INCREMENT_UNIQ='true'
            fi
        done
    done
    if [[ ${FULL_AND_INCREMENT_UNIQ} = 'true' ]];then
        send_wechat_work_robot 1 11 "全量备份与增量备份执行时间存在重复，同一天只能执行一个备份，请手动处理"
        exit 1
    elif [[ ${#FULL_BACKUP_TIME[@]} != ${#FULL_BACKUP_TIME_UNIQ[@]} ]];then
        send_wechat_work_robot 1 11 "全量备份策略执行时间存在重复日期，请手动处理"
        exit 1
    elif [[ ${#INCREMENT_BACKUP_TIME[@]} != ${#INCREMENT_BACKUP_TIME_UNIQ[@]} ]];then
        send_wechat_work_robot 1 11 "增量备份策略执行时间存在重复日期，请手动处理"
        exit 1
    elif [[ ${#FULL_BACKUP_TIME[@]} = 0 && ${#INCREMENT_BACKUP_TIME[@]} = 0 ]];then
        send_wechat_work_robot 1 11 "未设置备份策略，请手动处理"
        exit 1
    elif [[ ${INCREMENT_BACKUP_STATUS_UP} = 'true' ]];then
        logs "$(date +%Y/%m/%d--%T)       执行增量数据备份"
        increment_data_backup_start
    elif [[ ${FULL_BACKUP_STATUS_UP} = 'true' ]];then
        logs "$(date +%Y/%m/%d--%T)       执行全量数据备份"
        full_data_backup_start
    fi
}


# 脚本执行过程
logs "==========================================="
logs "$(date +%Y/%m/%d--%T)       开始执行数据备份"
SCRIPTS_START_TIME=$(date +%Y/%m/%d--%T)
logs "$(date +%Y/%m/%d--%T)       开始检测备份策略"
bakcup_tactics_check
delete_dateline_backup_file
